package com.whf.android.jar.app;

import android.app.Activity;
import android.os.Handler;
import android.text.TextUtils;
import android.webkit.URLUtil;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.Utils;
import com.joanzapata.iconify.IconFontDescriptor;
import com.joanzapata.iconify.Iconify;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.Logger;
import com.tencent.bugly.crashreport.CrashReport;
import com.whf.android.jar.net.rx.AddCookieInterceptor;
import com.whf.android.jar.net.rx.AddAuthorizationInterceptor;
import com.whf.android.jar.net.rx.AddTokenInterceptor;
import com.whf.android.jar.util.Density;
import com.whf.android.jar.util.log.LatteLogger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import okhttp3.Interceptor;
import okhttp3.logging.HttpLoggingInterceptor;

/**
 * 全局参数配置
 *
 * @author qf
 */
public final class Configurator {

    private static final HashMap<Object, Object> LATTE_CONFIGS = new HashMap<>();

    private static final Handler HANDLER = new Handler();

    private static final ArrayList<IconFontDescriptor> ICONS = new ArrayList<>();

    private static final ArrayList<Interceptor> INTERCEPTORS = new ArrayList<>();

    private Configurator() {
        LATTE_CONFIGS.put(ConfigKeys.CONFIG_READY, false);
        LATTE_CONFIGS.put(ConfigKeys.HANDLER, HANDLER);
    }

    static Configurator getInstance() {
        return Holder.INSTANCE;
    }

    final HashMap<Object, Object> getLatteConfigs() {
        return LATTE_CONFIGS;
    }


    private static class Holder {
        private static final Configurator INSTANCE = new Configurator();
    }

    /**
     * 开启bug的log输出功能
     */
    public final void configure() {
        initIcons();
        Logger.addLogAdapter(new AndroidLogAdapter() {
            @Override
            public boolean isLoggable(int priority, @Nullable String tag) {
                try {
                    return (boolean) LATTE_CONFIGS.get(ConfigKeys.LOGGABLE);
                } catch (Exception ex) {
                    return false;
                }
            }
        });
        LATTE_CONFIGS.put(ConfigKeys.CONFIG_READY, true);
        LATTE_CONFIGS.put(ConfigKeys.BAR_HEIGHT, BarUtils.getStatusBarHeight());
        // 初始化全局变量（完）
        Utils.init(Latte.getApplicationContext());
        // 界面宽度适配
        Density.setDensity(Latte.getApplicationContext(), Latte.getAdaptation());
        // 初始化BugLy(debug不初始化)
        if (!Latte.getDebug() && !TextUtils.isEmpty(Latte.getAppBugId())) {
            //当没有BugLy的id时，不初始化
            CrashReport.initCrashReport(Latte.getApplicationContext(), Latte.getAppBugId(), false);
        }
    }

    /**
     * 是否开启日志
     *
     * @param loggable:是否
     */
    public final Configurator withLoggable(boolean loggable) {
        LATTE_CONFIGS.put(ConfigKeys.LOGGABLE, loggable);
        return this;
    }

    /**
     * 桌面图标
     *
     * @param icon:图标
     */
    public final Configurator withAppIcon(int icon) {
        LATTE_CONFIGS.put(ConfigKeys.APP_ICON, icon);
        return this;
    }


    /**
     * 界面适配
     * 1920*1080 ->540f
     * 1334*750 ->375f
     *
     * @param width:分辨率
     */
    public final Configurator withAdaptation(float width) {
        LATTE_CONFIGS.put(ConfigKeys.ADAPTATION, width);
        return this;
    }

    /**
     * @param host：基础服务
     */
    public final Configurator withApiHost(String host) {
        if (!URLUtil.isNetworkUrl(host)) {
            throw new NullPointerException("基础服务地址不是url");
        }
        LATTE_CONFIGS.put(ConfigKeys.API_HOST, host);
        return this;
    }

    /**
     * @param field：基础服务的下级域名
     */
    public final Configurator withApiField(String field) {
        if (TextUtils.isEmpty(field)) {
            LATTE_CONFIGS.put(ConfigKeys.API_FIELD, "");
        } else {
            LATTE_CONFIGS.put(ConfigKeys.API_FIELD, "/" + field + "/");
        }
        return this;
    }

    /**
     * @param server：版本更新服务
     */
    public final Configurator withApiCheckVersion(String server) {
        LATTE_CONFIGS.put(ConfigKeys.API_CHECK_VERSION, server);
        return this;
    }

    /**
     * @param server：版本更新记录
     */
    public final Configurator withApiCheckHistory(String server) {
        LATTE_CONFIGS.put(ConfigKeys.API_CHECK_HISTORY, server);
        return this;
    }

    /**
     * 项目的ID（app云的）
     *
     * @param appId:项目ID
     */
    public final Configurator withAppId(String appId) {
        LATTE_CONFIGS.put(ConfigKeys.APP_ID, appId);
        return this;
    }

    /**
     * 项目的ID（BugLy的）
     *
     * @param appId:项目ID
     */
    public final Configurator withAppBugId(String appId) {
        LATTE_CONFIGS.put(ConfigKeys.APP_BUG_ID, appId);
        return this;
    }

    /**
     * @param is:是否给截屏添加水印
     */
    public final Configurator withScreenshot(boolean is) {
        LATTE_CONFIGS.put(ConfigKeys.PROHIBIT_SCREENSHOT, is);
        return this;
    }

    /**
     * @param is:检查证书(ssl)
     */
    public final Configurator withTrustCertificate(boolean is) {
        LATTE_CONFIGS.put(ConfigKeys.TRUST_CERTIFICATE, is);
        return this;
    }

    /**
     * 项目需切换服务
     *
     * @param isServer:需切换服务
     */
    public final Configurator withSwitchingServices(boolean isServer) {
        LATTE_CONFIGS.put(ConfigKeys.SWITCHING_SERVICES, isServer);
        return this;
    }

    /**
     * 项目引导时间
     *
     * @param guide:项目引导时间
     */
    public final Configurator withGuide(int guide) {
        LATTE_CONFIGS.put(ConfigKeys.APP_GUIDE, guide);
        return this;
    }

    /**
     * 是否显示引导时间
     *
     * @param guide:是否显示引导时间
     */
    public final Configurator withGuide(boolean guide) {
        LATTE_CONFIGS.put(ConfigKeys.APP_IS_GUIDE, guide);
        return this;
    }

    /**
     * @param fontScale:字体缩放比例
     */
    public final Configurator fontScale(float fontScale) {
        LATTE_CONFIGS.put(ConfigKeys.APP_FONT_SCALE, fontScale);
        return this;
    }

    /**
     * @param watermark:水印显示内容
     */
    public final Configurator withWatermark(String... watermark) {
        LATTE_CONFIGS.put(ConfigKeys.WATERMARK, Arrays.asList(watermark));
        return this;
    }

    /**
     * @param token:token
     */
    public final Configurator withToken(String token) {
        LATTE_CONFIGS.put(ConfigKeys.TOKEN, token);
        return this;
    }

    /**
     * @param uid:Uid
     */
    public final Configurator withUid(String uid) {
        LATTE_CONFIGS.put(ConfigKeys.UID, uid);
        return this;
    }

    /**
     * 项目的包名
     *
     * @param applicationId:包名
     */
    public final Configurator withApplicationId(String applicationId) {
        LATTE_CONFIGS.put(ConfigKeys.APPLICATION_ID, applicationId);
        return this;
    }

    /**
     * 网络建立连接超时
     *
     * @param timeOut:默认25秒
     */
    public final Configurator withTimeOut(int timeOut) {
        if (timeOut < 25) {
            //网络请求超时时间最少设置25秒
            timeOut = 25;
        }
        LATTE_CONFIGS.put(ConfigKeys.NET_TIME_OUT, timeOut);
        return this;
    }


    /**
     * 网络请求超时时间
     * <p> 整个网络最多使用时间
     *
     * @param timeOut:的默认值为，代表不考虑请求的超时
     */
    public final Configurator withTimeOutCall(int timeOut) {
        if (timeOut < 0) {
            return this;
        }
        LATTE_CONFIGS.put(ConfigKeys.NET_TIME_OUT_CALL, timeOut);
        return this;
    }

    /**
     * 设置登录失效标识
     *
     * @param sign:登录失效标识
     */
    public final Configurator withSignExpiration(int sign) {
        LATTE_CONFIGS.put(ConfigKeys.SIGN_EXPIRATION, sign);
        return this;
    }

    /**
     * 设置版本号
     *
     * @param versionCode:版本号
     */
    public final Configurator withVersionCode(int versionCode) {
        LATTE_CONFIGS.put(ConfigKeys.VERSION_CODE, versionCode);
        return this;
    }

    /**
     * 设置版本号
     *
     * @param versionName:版本号
     */
    public final Configurator withVersionName(String versionName) {
        LATTE_CONFIGS.put(ConfigKeys.VERSION_NAME, versionName);
        return this;
    }

    /**
     * 上传单文件时表单字段的名称
     *
     * @param name:表单字段的名称
     */
    public Configurator withUploadFile(String name) {
        LATTE_CONFIGS.put(ConfigKeys.UPLOAD_FILE, name);
        return this;
    }

    /**
     * 上传多文件时表单字段的名称
     *
     * @param name:表单字段的名称
     */
    public Configurator withUploadFiles(String name) {
        LATTE_CONFIGS.put(ConfigKeys.UPLOAD_FILES, name);
        return this;
    }

    /**
     * 设置请求成功代号
     *
     * @param success:请求成功代号
     */
    public final Configurator withCodeSuccess(String success) {
        LATTE_CONFIGS.put(ConfigKeys.CODE_SUCCESS, success);
        return this;
    }

    /**
     * 设置成功信息代号key
     *
     * @param keyCode:成功信息代号key
     */
    public final Configurator withKeyCode(String keyCode) {
        LATTE_CONFIGS.put(ConfigKeys.KEY_CODE, keyCode);
        return this;
    }

    /**
     * 设置成功信息key
     *
     * @param keyData:成功信息key
     */
    public final Configurator withKeyData(String keyData) {
        LATTE_CONFIGS.put(ConfigKeys.KEY_DATA, keyData);
        return this;
    }

    /**
     * 设置错误信息key
     *
     * @param keyMessage:错误信息key
     */
    public final Configurator withKeyMessage(String keyMessage) {
        LATTE_CONFIGS.put(ConfigKeys.KEY_MESSAGE, keyMessage);
        return this;
    }

    /**
     * 请求延迟时间
     *
     * @param delayed:毫秒
     */
    public final Configurator withLoaderDelayed(long delayed) {
        LATTE_CONFIGS.put(ConfigKeys.LOADER_DELAYED, delayed);
        return this;
    }

    private void initIcons() {
        if (ICONS.size() > 0) {
            final Iconify.IconifyInitializer initializer = Iconify.with(ICONS.get(0));
            for (int i = 1; i < ICONS.size(); i++) {
                initializer.with(ICONS.get(i));
            }
        }
    }

    /**
     * 全局Icon
     *
     * @param descriptor:IconFontDescriptor
     */
    public final Configurator withIcon(IconFontDescriptor descriptor) {
        ICONS.add(descriptor);
        return this;
    }

    /**
     * okHttp拦截器
     */
    public final Configurator withInterceptor() {
        INTERCEPTORS.add(new AddCookieInterceptor());
        LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    /**
     * okHttp拦截器
     */
    public final Configurator withToken() {
        INTERCEPTORS.add(new AddTokenInterceptor());
        LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    /**
     * okHttp拦截器
     */
    public final Configurator withObservable() {
        INTERCEPTORS.add(new AddAuthorizationInterceptor());
        LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    /**
     * okHttp拦截器
     *
     * @param interceptor:Interceptor
     */
    public final Configurator withInterceptor(Interceptor interceptor) {
        INTERCEPTORS.add(interceptor);
        LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    /**
     * okHttp日志打印拦截器拦截器
     */
    public final Configurator withHttpLogging() {
        try {
            final boolean isLoggable = (boolean) LATTE_CONFIGS.get(ConfigKeys.LOGGABLE);
            if (isLoggable) {
                INTERCEPTORS.add(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(@NonNull String s) {
                        LatteLogger.i(s);
                    }
                }).setLevel(HttpLoggingInterceptor.Level.BASIC));
                LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return this;
    }

    /**
     * okHttp拦截器
     *
     * @param interceptors:Interceptor
     */
    public final Configurator withInterceptors(ArrayList<Interceptor> interceptors) {
        INTERCEPTORS.addAll(interceptors);
        LATTE_CONFIGS.put(ConfigKeys.INTERCEPTOR, INTERCEPTORS);
        return this;
    }

    /**
     * 微信支付
     *
     * @param appId:
     */
    public final Configurator withWeChatAppId(String appId) {
        LATTE_CONFIGS.put(ConfigKeys.WE_CHAT_APP_ID, appId);
        return this;
    }

    /**
     * 微信支付appSecret
     *
     * @param appSecret:
     */
    public final Configurator withWeChatAppSecret(String appSecret) {
        LATTE_CONFIGS.put(ConfigKeys.WE_CHAT_APP_SECRET, appSecret);
        return this;
    }

    /**
     * 全局activity
     *
     * @param activity:Activity
     */
    public final Configurator withActivity(Activity activity) {
        LATTE_CONFIGS.put(ConfigKeys.ACTIVITY, activity);
        return this;
    }

    /**
     * javascript接口
     *
     * @param name:
     */
    public Configurator withJavascriptInterface(@NonNull String name) {
        LATTE_CONFIGS.put(ConfigKeys.JAVASCRIPT_INTERFACE, name);
        return this;
    }

    /**
     * @param mourning:灰白界面
     */
    public Configurator withMourning(boolean mourning) {
        LATTE_CONFIGS.put(ConfigKeys.MOURNING, mourning);
        return this;
    }

    /**
     * @param errorServer:是否拦截服务器错误
     */
    public Configurator withServerError(boolean errorServer) {
        LATTE_CONFIGS.put(ConfigKeys.SERVER_ERROR, errorServer);
        return this;
    }

    /***
     * 聊天服务器的HOST
     * @param host:浏览器HOST
     */
    public Configurator withImHost(String host) {
        LATTE_CONFIGS.put(ConfigKeys.IM_HOST, host);
        return this;
    }

    /***
     * 浏览器加载的HOST
     * @param host:浏览器HOST
     */
    public Configurator withWebHost(String host) {
        LATTE_CONFIGS.put(ConfigKeys.WEB_HOST, host);
        return this;
    }

    /***
     * h5的HOST
     * @param host:h5的HOST
     */
    public Configurator withFrontHost(String host) {
        LATTE_CONFIGS.put(ConfigKeys.FRONT_HOST, host);
        return this;
    }

    /***
     * 附件的HOST
     * @param ftpHost:附件的HOST
     */
    public Configurator withFtpHost(String ftpHost) {
        LATTE_CONFIGS.put(ConfigKeys.FTP_HOST, ftpHost);
        return this;
    }

    /***
     * bi数仓的HOST
     * @param biHost:bi的HOST
     */
    public Configurator withBiHost(String biHost) {
        LATTE_CONFIGS.put(ConfigKeys.BI_HOST, biHost);
        return this;
    }

    /***
     * 其他的HOST
     * @param otherHost:other的HOST
     */
    public Configurator withOtherHost(String otherHost) {
        LATTE_CONFIGS.put(ConfigKeys.OTHER_HOST, otherHost);
        return this;
    }


    private void checkConfiguration() {
        final boolean isReady = (boolean) LATTE_CONFIGS.get(ConfigKeys.CONFIG_READY);
        if (!isReady) {
            throw new RuntimeException("Configuration is not ready,call configure");
        }
    }

    @SuppressWarnings("unchecked")
    final <T> T getConfiguration(Object key) {
        checkConfiguration();
        final Object value = LATTE_CONFIGS.get(key);
        if (value == null) {
            throw new NullPointerException(key.toString() + " IS NULL");
        }
        return (T) LATTE_CONFIGS.get(key);
    }
}
